﻿using System;
using System.Collections.Generic;
using System.Text;

using System.Collections;

namespace XKSocket
{
    /// <summary>
    /// Int ID Pool
    /// 保证Pool中始终有 _iPoolSize 数量的ID可提供分配
    /// </summary>
    internal class ConnectionIDPool
    {
        public static List<int> _IDPool = new List<int>();
        static bool _IsFirstExe = true;
        static object _lockobj = new object();
        static int _iPoolSize = XKSktConfig.IDPoolSize;

        static void InitPool()
        {
            _IsFirstExe = false;
            for (int i = 0; i < _iPoolSize; i++)
            {
                _IDPool.Add(i);
            }
        }

        public static int PopID()
        {
            lock (_lockobj)
            {
                if (_IsFirstExe)
                {
                    InitPool();
                }
                _IDPool.Add(_IDPool[_IDPool.Count - 1] + 1);
                _IDPool.Sort();
                
                //随机从Pool里面取ID
                //上层应保证所有对象都释放了ID,在把ID归还到Pool中
                //注意:
                //上层可能多个对象使用此ID,当其中一个对象释放,其它对象也跟着释放此ID,ID归还到Pool中
                //而如果上层ID已归还,但还有对象可能由于多线程原因未能及时释放
                //归还的ID又被重新分配,那么上层可能引发未知问题
                int iIndex = (new Random(DateTime.Now.Millisecond)).Next(0, _iPoolSize - 1); 
                int val = _IDPool[iIndex];
                _IDPool.RemoveAt(iIndex);

                return val;
            }
        }
        public static void PushID(int val)
        {
            lock (_lockobj)
            {
                if (_IsFirstExe)
                {
                    InitPool();
                }

                _IDPool.Insert(0, val);
                _IDPool.Sort();
                _IDPool.RemoveAt(_IDPool.Count - 1);               
            }
        }
    }
}
